#include "stdafx.h"
#include "exportanim.h"
#include "max.h"
#include "modstack.h"
#include "matrix.h"

//////////////////////////////////////////////////////////////////////////////////////////////
// CExportBone
//////////////////////////////////////////////////////////////////////////////////////////////
CExportBone* CExportBone::BuildFromINode( INode *N, Interval Time, TimeValue Step )
{
    CExportBone* result = new CExportBone();

    result->NumFrames = Time.Duration()/Step+1;
    result->Frames = new CMatrix[result->NumFrames];

    int i = 0;
    for ( TimeValue t = Time.Start(); t <= Time.End(); t += Step )
    {
        ASSERT(i<=result->NumFrames);
        Matrix3 InvMat = N->GetParentNode()->GetObjectTM( t );
        Matrix3 Mat = N->GetObjectTM( t );
        InvMat.SetColumn( 0, InvMat.GetColumn(0)*-1 );
        Mat.SetColumn( 0, Mat.GetColumn(0)*-1 );
        InvMat.Invert();
        Matrix3 M = Mat*InvMat;
        result->Frames[i].e[0][0] = M.GetRow(0).x;
        result->Frames[i].e[0][1] = M.GetRow(0).y;
        result->Frames[i].e[0][2] = M.GetRow(0).z;
        result->Frames[i].e[0][3] = 0.f;
        result->Frames[i].e[1][0] = M.GetRow(1).x;
        result->Frames[i].e[1][1] = M.GetRow(1).y;
        result->Frames[i].e[1][2] = M.GetRow(1).z;
        result->Frames[i].e[1][3] = 0.f;
        result->Frames[i].e[2][0] = M.GetRow(2).x;
        result->Frames[i].e[2][1] = M.GetRow(2).y;
        result->Frames[i].e[2][2] = M.GetRow(2).z;
        result->Frames[i].e[2][3] = 0.f;
        result->Frames[i].e[3][0] = M.GetTrans().x;
        result->Frames[i].e[3][1] = M.GetTrans().y;
        result->Frames[i].e[3][2] = M.GetTrans().z;
        result->Frames[i].e[3][3] = 1.f;
        i++;
    }

    return result;
}

void CExportBone::Save( /*cFile &F*/ )
{
    //F.Write( Frames, NumFrames*sizeof(CMatrix) );
}

//////////////////////////////////////////////////////////////////////////////////////////////
// CExportAnimation
//////////////////////////////////////////////////////////////////////////////////////////////
void CExportAnimation::Save( /*cFile &F, cLogFile &logF*/ )
{
    /*
    ((CStream&)F).Write( GetName().m_szString );
    _FWRITE( F, m_iStartBone );
    _FWRITE( F, NumFrames );
    _FWRITE( F, BonesAnim.size() );
    logF.WriteStr( "%s\t\t| %d\t| %d\r\n", GetName().c_str(), m_iStartBone, NumFrames );
    for ( int i = 0; i < NumFrames; i++ )
    	ForEach(BonesAnim,CExportBone)
    		F.Write(I->Ptr->Frames+i,sizeof(D3DXMATRIX));
    		*/
}

void CExportAnimation::AddBoneAnim( INode *N, Interval Time, TimeValue Step )
{
    CExportBone* O = CExportBone::BuildFromINode(N, Time, Step);
    if ( O ) BonesAnim.push_back( CExportBone::BuildFromINode(N, Time, Step) );

    int NumChildren = N->NumberOfChildren();
    for ( int i = 0; i < NumChildren; i++ )
    {
        Interface *ip = GetCOREInterface();
        ip->ProgressUpdate( (i*100)/NumChildren, FALSE, "Building anim data..." );
        AddBoneAnim( N->GetChildNode( i ), Time, Step );
    }
}

CExportAnimation* CExportAnimation::BuildFromNode( INode *N, Interval Time, TimeValue Step )
{
    CExportAnimation *result = new CExportAnimation();
    result->SetName( "kakas" );
    result->NumFrames = Time.Duration()/Step+1;
    result->AddBoneAnim( N, Time, Step );
    return result;
}

CExportAnimation* CExportAnimation::Load( /*cFile &F*/ )
{
    CExportAnimation* result = new CExportAnimation();
    /*
    char tmpstr[MAX_STRING];
    result->SetName(F.ReadString(tmpstr));
    _FREAD( F, result->m_iStartBone );
    _FREAD( F, result->NumFrames );
    int NumBones;
    _FREAD( F, NumBones );
    int i = 0;
    for ( i = 0; i < NumBones; i++ )
    {
    	result->BonesAnim.Add( new CExportBone() );
    	result->BonesAnim[i]->Frames = new CMatrix[result->NumFrames];
    }
    for ( i = 0; i < result->NumFrames; i++ )
    	for ( int j = 0; j < NumBones; j++ )
    		F.Read( result->BonesAnim[j]->Frames+i, sizeof(CMatrix) );

    		*/
    return result;
}

//////////////////////////////////////////////////////////////////////////////////////////////
// CAnimData
//////////////////////////////////////////////////////////////////////////////////////////////
const char* CExportAnimData::AnimPath = "animations\\";

CExportAnimData* CExportAnimData::Load( /*const CString &szName, bool usedefpath*/ )
{   /*
    CString szFullName;
    if ( usedefpath )
    {
    	szFullName = AnimPath;
    	//strcpy( NameWithPath, AnimPath );
    	//strcat( NameWithPath, strrelpath(name,AnimPath) );
    	//strcat( NameWithPath, ".anm" );
    	ASSERT(false);
    } else {
    	szFullName = szName;
    }

    cFile F( szFullName );
    CExportAnimData *result = new CExportAnimData();

    result->SetName( szFullName );

    int NumAnims;
    _FREAD( F, NumAnims );
    for ( int i = 0; i < NumAnims; i++ )
    {
    	result->Anims.Add(CExportAnimation::Load( F ));
    }

    F.Close();
    */
    CExportAnimData *result = new CExportAnimData();
    return result;
}

void CExportAnimData::UpdateListBox( HWND hWnd )
{
    SendMessage( hWnd, LB_RESETCONTENT, NULL, NULL );
    for (vector<CExportAnimation*>::const_iterator it = Anims.begin(); it != Anims.end(); ++it)
        SendMessage( hWnd, LB_ADDSTRING, NULL, (LPARAM)(*it)->GetName().c_str() );
}

void CExportAnimData::Save( const string& fn )
{   /*
    cFile F;
    F.Create( fn );

    cLogFile logf( fn.RemExt()+".log" );

    logf.WriteLn( "Name\t\t| StartBone | Length(frames)" );
    logf.WriteLn( "    \t\t|           |               " );

    _FWRITE( F, Anims.Count );
    ForEach(Anims,CExportAnimation) I->Ptr->Save( F, logf );

    F.Close();
    logf.Close();
    */
}

void CExportAnimData::Clear()
{
    for (vector<CExportAnimation*>::const_iterator it = Anims.begin(); it != Anims.end(); ++it)
    {
        delete *it;
    }
    Anims.clear();
}

